package com.polaris.live.utils.zego.beauty

import com.blankj.utilcode.util.StringUtils
import com.faceunity.authpack
import com.faceunity.wrapper.faceunity
import com.polaris.live.common.constant.AppConst.Beautify
import com.polaris.live.common.constant.AppConst.BeautifyFilter
import com.polaris.live.common.constant.AppConst.DeformType
import com.polaris.live.common.constant.CacheConst
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.util.LogExt
import com.polaris.live.resp.back_resp.BeautyBean
import com.polaris.live.resp.back_resp.BeautyDataItem
import com.polaris.live.resp.back_resp.BeautyItem
import com.polaris.live.translation.R
import com.polaris.live.utils.file.FileUtils
import com.tencent.mmkv.MMKV
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch

/**
 * faceUnity管理器
 *
 * @author Created by lucas on 2023/12/6 13:27
 * @since 1.0.0
 */
object FaceManager {

    private const val TAG = "FaceManager"

    private var mInitialized = false
    private var mBeautyBytes: ByteArray? = null

    private val mUpdateFaceUnitySet = mutableListOf<FaceUnity>()

    /**
     * 初始化
     */
    fun init() {
        GlobalScope.launch(CoroutineScopeManager.ioDispatcher) {
            if (mInitialized) {
                return@launch
            }

            faceunity.fuSetLogLevel(3)

            faceunity.fuCreateEGLContext()
            val fuSetup = faceunity.fuSetup(ByteArray(0), authpack.A())
            mInitialized = faceunity.fuIsLibraryInit() == 1
            faceunity.fuReleaseEGLContext()

            LogExt.logI(TAG, "fuSetup = $fuSetup, initSuccess = $mInitialized")

            //这里先获取一次数据
            getBeauty()
            getBeautyFilter()

            val aiBytes = FileUtils.readAssetsFile("model/ai_face_processor_lite.bundle")
            faceunity.fuLoadAIModelFromPackage(aiBytes, faceunity.FUAITYPE_FACEPROCESSOR)

            if (mInitialized) {
                mBeautyBytes = FileUtils.readAssetsFile("graphics/face_beautification.bundle")
            }
        }
    }

    /**
     * 创建一个美颜工具类
     */
    fun createFaceUnity(): FaceUnity {
        return FaceUnity(mBeautyBytes).apply {
            mUpdateFaceUnitySet.add(this)
            setBeautyInfoToFaceUnity(this)
        }

    }

    /**
     * 将美颜参数设置进去
     */
    private fun setBeautyInfoToFaceUnity(faceUnity: FaceUnity) {
        getBeauty().item.forEachIndexed { index, beautyDataItem ->
            beautyDataItem.beautyItem.forEach { beautyItem ->
                when (index) {
                    0 -> faceUnity.applyBlur(beautyItem.type, beautyItem)
                    1 -> faceUnity.applyDeform(beautyItem.type, beautyItem)
                    2 -> {
                        if (beautyItem.type == getBeautyFilter()) {
                            faceUnity.applyFilter(beautyItem)
                            return@forEachIndexed
                        }
                    }
                }
            }
        }
    }


    /**
     * 解绑一个FaceUnity
     */
    fun unbindFaceUnity(faceUnity: FaceUnity) {
        mUpdateFaceUnitySet.remove(faceUnity)
    }

    private var mBeautyFilter: Int? = null

    private var mBeautyList = mutableListOf<BeautyDataItem>() //当前设置的参数

    /**
     * 获取美颜配置
     */
    fun getBeauty(): BeautyBean {

        val last = getBeautyInfo() //上次设置的数据

        val tempBeautyList = mutableListOf<BeautyDataItem>()
        val titles = getTitles()
        titles.forEach {
            val list = when (titles.indexOf(it)) {
                0 -> getBeautifyList()
                1 -> getDeformList()
                else -> getFilterList()
            }
            tempBeautyList.add(
                BeautyDataItem(
                    title = it.title,
                    type = it.type,
                    beautyItem = list
                )
            )
        }
        last?.item?.forEach { lastItem ->
            tempBeautyList.forEach { default ->
                if (lastItem.type == default.type) {
                    lastItem.beautyItem.forEach { lastBeauty ->
                        default.beautyItem.find { it.type == lastBeauty.type }?.intensity = lastBeauty.intensity
                    }
                }
            }
        }
        mBeautyList = tempBeautyList
        return BeautyBean(tempBeautyList).apply {
            setBeautyInfo(this)
        }
    }

    /**
     * 获取美颜滤镜选择
     */
    fun getBeautyFilter(): Int {
        return mBeautyFilter ?: let {
            val kv = MMKV.mmkvWithID(CacheConst.APP)
            kv.decodeInt(CacheConst.FACE_BEAUTY_FILTER, BeautyFilterEnum.ORIGIN.type).apply {
                mBeautyFilter = this
            }
        }
    }

    /**
     * 存用户美颜滤镜
     */
    fun setBeauty(filterType: Int) {
        val kv = MMKV.mmkvWithID(CacheConst.APP)
        kv.encode(CacheConst.FACE_BEAUTY_FILTER, filterType)
        mBeautyFilter = filterType
    }


    fun getBeautyInfo(): BeautyBean? {
        val kv = MMKV.mmkvWithID(CacheConst.APP)
        return kv.decodeParcelable(CacheConst.FACE_BEAUTY_INFO, BeautyBean::class.java)
    }

    /**
     * 存用户美颜信息
     */
    fun setBeautyInfo(beautyBean: BeautyBean) {
        val kv = MMKV.mmkvWithID(CacheConst.APP)
        kv.encode(CacheConst.FACE_BEAUTY_INFO, beautyBean)
    }

    private fun getTitles(): List<BeautyDataItem> {
        return listOf(
            BeautyDataItem(StringUtils.getString(R.string.beauty_beautify), Beautify.BEAUTIFY),
            BeautyDataItem(StringUtils.getString(R.string.beauty_deform), DeformType.DEFORM),
            BeautyDataItem(StringUtils.getString(R.string.beauty_lookup), BeautifyFilter.FILTER),
        )
    }

    //美颜默认值
    private fun getBeautifyList(): List<BeautyItem> {
        return listOf(
            BeautyItem(
                name = StringUtils.getString(R.string.beauty_bright),
                type = Beautify.MEIBAI,
                intensity = Beautify.DEFAULT_MEIBAI,
                image = com.polaris.live.R.drawable.meibai
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.beauty_soften),
                type = Beautify.MOPI,
                intensity = Beautify.DEFAULT_MOPI,
                image = com.polaris.live.R.drawable.mopi
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.beauty_clarity),
                type = Beautify.QINGXI,
                intensity = Beautify.DEFAULT_QINGXI,
                image = com.polaris.live.R.drawable.qingxi
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.beauty_teeth),
                type = Beautify.BAIYA,
                intensity = Beautify.DEFAULT_BAIYA,
                image = com.polaris.live.R.drawable.baiya
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.beauty_eyebrighten),
                type = Beautify.LIANGYAN,
                intensity = Beautify.DEFAULT_LIANGYAN,
                image = com.polaris.live.R.drawable.liangyan
            ),
        )
    }

    //美型默认值
    private fun getDeformList(): List<BeautyItem> {
        return listOf(
            BeautyItem(
                name = StringUtils.getString(R.string.deform_shoulian),
                type = DeformType.SHOULIAN,
                intensity = DeformType.DEFAULT_SHOULIAN,
                image = com.polaris.live.R.drawable.shoulian
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_dayan),
                type = DeformType.DAYAN,
                intensity = DeformType.DEFAULT_DAYAN,
                image = com.polaris.live.R.drawable.dayan
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_yanjingweizhi),
                type = DeformType.YANJINGWEIZHI,
                intensity = DeformType.DEFAULT_YANJINGWEIZHI,
                image = com.polaris.live.R.drawable.yanjingweizhi
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_fajixian),
                type = DeformType.FAJIXIAN,
                intensity = DeformType.DEFAULT_FAJIXIAN,
                image = com.polaris.live.R.drawable.fajixian
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_xiaba),
                type = DeformType.XIABA,
                intensity = DeformType.DEFAULT_XIABA,
                image = com.polaris.live.R.drawable.xiaba
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_shoubi),
                type = DeformType.SHOUBI,
                intensity = DeformType.DEFAULT_SHOUBI,
                image = com.polaris.live.R.drawable.shoubi
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_bichang),
                type = DeformType.BICHANG,
                intensity = DeformType.DEFAULT_BICHANG,
                image = com.polaris.live.R.drawable.bichang
            ),
            BeautyItem(
                name = StringUtils.getString(R.string.deform_zuixing),
                type = DeformType.ZUIXING,
                intensity = DeformType.DEFAULT_ZUIXING,
                image = com.polaris.live.R.drawable.zuixing
            ),
        )
    }

    //美型默认值
    private val deformList = listOf(
        BeautyItem(
            name = StringUtils.getString(R.string.deform_shoulian),
            type = DeformType.SHOULIAN,
            intensity = DeformType.DEFAULT_SHOULIAN,
            image = com.polaris.live.R.drawable.shoulian
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_dayan),
            type = DeformType.DAYAN,
            intensity = DeformType.DEFAULT_DAYAN,
            image = com.polaris.live.R.drawable.dayan
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_yanjingweizhi),
            type = DeformType.YANJINGWEIZHI,
            intensity = DeformType.DEFAULT_YANJINGWEIZHI,
            image = com.polaris.live.R.drawable.yanjingweizhi
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_fajixian),
            type = DeformType.FAJIXIAN,
            intensity = DeformType.DEFAULT_FAJIXIAN,
            image = com.polaris.live.R.drawable.fajixian
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_xiaba),
            type = DeformType.XIABA,
            intensity = DeformType.DEFAULT_XIABA,
            image = com.polaris.live.R.drawable.xiaba
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_shoubi),
            type = DeformType.SHOUBI,
            intensity = DeformType.DEFAULT_SHOUBI,
            image = com.polaris.live.R.drawable.shoubi
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_bichang),
            type = DeformType.BICHANG,
            intensity = DeformType.DEFAULT_BICHANG,
            image = com.polaris.live.R.drawable.bichang
        ),
        BeautyItem(
            name = StringUtils.getString(R.string.deform_zuixing),
            type = DeformType.ZUIXING,
            intensity = DeformType.DEFAULT_ZUIXING,
            image = com.polaris.live.R.drawable.zuixing
        ),
    )

    private fun getFilterList(): List<BeautyItem> {
        return buildList {
            BeautyFilterEnum.values().forEach {
                add(
                    BeautyItem(
                        name = StringUtils.getString(it.stringId),
                        type = it.type,
                        intensity = 50,
                        image = it.iconId
                    )
                )
            }
        }
    }

    /**
     * 修改美颜的参数
     */
    fun setBeautyEvent(item: BeautyItem, type: Long) {
        mUpdateFaceUnitySet.forEach {
            when (type) {
                Beautify.BEAUTIFY -> {
                    it.applyBlur(item.type, item)
                    mBeautyList.getOrNull(0)?.beautyItem?.forEach { beauty ->
                        if (beauty.type == item.type) {
                            beauty.intensity = item.intensity
                        }
                    }
                }

                DeformType.DEFORM -> {
                    it.applyDeform(item.type, item)
                    mBeautyList.getOrNull(1)?.beautyItem?.forEach { beauty ->
                        if (beauty.type == item.type) {
                            beauty.intensity = item.intensity
                        }
                    }
                }

                BeautifyFilter.FILTER -> {
                    it.applyFilter(item)
                    mBeautyList.getOrNull(2)?.beautyItem?.forEach { beauty ->
                        if (beauty.type == item.type) {
                            beauty.intensity = item.intensity
                        }
                    }
                }
            }
        }
        setBeautyInfo(BeautyBean(mBeautyList))
    }

    fun setBeautyParamFilter(name: String?) {
        var i = 0
        val count = mUpdateFaceUnitySet.size
        while (i < count) {
            mUpdateFaceUnitySet[i].setBeautyParamFilter(name)
            i++
        }
    }

    fun setBeautyParamFilterLevel(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamFilterLevel(level)
        }
    }

    //磨皮
    fun setBeautyParamBlur(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamBlur(level)
        }
    }

    //美白
    fun setBeautyParamWhitening(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamWhitening(level)
        }
    }

    //红润
    fun setBeautyParamRedLevel(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamRosy(level)
        }
    }

    //亮眼
    fun setBeautyParamEyesBright(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamEyesBright(level)
        }
    }

    //锐化
    fun setBeautyParamSharpen(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamSharpen(level)
        }
    }

    //美牙
    fun setBeautyParamTooth(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamTooth(level)
        }
    }

    //黑眼圈
    fun setBeautyParamBlackEyes(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamBlackEyes(level)
        }
    }

    //去法令纹
    fun setBeautyParamNasolabial(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamNasolabial(level)
        }
    }

    //瘦脸
    fun setBeautyParamThinning(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamThinning(level)
        }
    }

    //v脸
    fun setBeautyParamFaceV(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamFaceV(level)
        }
    }

    //窄脸
    fun setBeautyParamFaceNarrow(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamFaceNarrow(level)
        }
    }

    //小脸
    fun setBeautyParamFaceSmall(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamFaceSmall(level)
        }
    }

    //大眼
    fun setBeautyParamEnlarging(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamEnlarging(level)
        }
    }

    //开圆眼
    fun setBeautyParamEyeCircle(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamEyeCircle(level)
        }
    }

    //下巴
    fun setBeautyParamChin(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamChin(level)
        }
    }

    //额头
    fun setBeautyParamForehead(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamForehead(level)
        }
    }

    //瘦鼻
    fun setBeautyParamNose(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamNose(level)
        }
    }

    //嘴型
    fun setBeautyParamMouth(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamMouth(level)
        }
    }

    //开眼角
    fun setBeautyParamCanthus(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamCanthus(level)
        }
    }

    //眼距
    fun setBeautyParamEyeSpace(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamEyeSpace(level)
        }
    }

    //眼睛角度
    fun setBeautyParamEyeRotate(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamEyeRotate(level)
        }
    }

    //长鼻
    fun setBeautyParamNoseLong(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamNoseLong(level)
        }
    }

    //人中
    fun setBeautyParamPhiltrum(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamPhiltrum(level)
        }
    }

    //微笑嘴角
    fun setBeautyParamSmile(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamSmile(level)
        }
    }

    //瘦颧骨
    fun setBeautyParamCheekbones(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamCheekbones(level)
        }
    }

    //瘦下颌骨
    fun setBeautyParamJawLower(level: Float) {
        mUpdateFaceUnitySet.forEach {
            it.setBeautyParamJawLower(level)
        }
    }
}